module Main {
  type @getConfig = (string): string
  type @isCertMode = (): boolean
  type @getTimestamp = (): string
  type @sign = (map[string]string, map[string]any, map[string]string, string): string
  type @getMerchantCertSN = (): string
  type @getAlipayRootCertSN = (): string
  type @toUrlEncodedRequestBody = (map[string]any, map[string]string): bytes
  type @readAsJson = ($Response, string): object
  type @getAlipayCertSN = (object): string
  type @extractAlipayPublicKey = (string): string
  type @verify = (object, string): boolean
  type @toRespModel = (object): object
  type @generatePage = (string, map[string]string, map[string]any, map[string]string, string): string
  type @getSdkVersion = (): string

  init(); 

  model IdentityParam {
    identityType: string(name='identity_type'),
    certType: string(name='cert_type'),
    certName: string(name='cert_name'),
    certNo: string(name='cert_no')
  }

  model MerchantConfig {
    returnUrl: string(name='return_url')
  }

  model AlipayUserCertifyOpenInitializeResponse {
    httpBody: string(name='http_body', description='响应原始字符串'),
    code: string(name='code'),
    msg: string(name='msg'),
    subCode: string(name='sub_code'),
    subMsg: string(name='sub_msg'),

    certifyId: string(name='certify_id')
  }

  model AlipayUserCertifyOpenCertifyResponse {
    body: string(name='body', description='认证服务请求地址')
  }

  model AlipayUserCertifyOpenQueryResponse {
    httpBody: string(name='http_body', description='响应原始字符串'),
    code: string(name='code'),
    msg: string(name='msg'),
    subCode: string(name='sub_code'),
    subMsg: string(name='sub_msg'),

    passed: string(name='passed'),
    identityInfo: string(name='identity_info'),
    materialInfo: string(name='material_info')
  }

  api init(outerOrderNo: string, bizCode: string, identityParam: IdentityParam, merchantConfig: MerchantConfig): AlipayUserCertifyOpenInitializeResponse {
    var systemParams: map[string]string = {
      method = 'alipay.user.certify.open.initialize',

      app_id = @getConfig('appId'),
      timestamp = @getTimestamp(),
      format = 'json',
      version = '1.0',
      alipay_sdk = @getSdkVersion(),
      charset = 'UTF-8',
      sign_type = @getConfig('signType'),
      app_cert_sn = @getMerchantCertSN(),
      alipay_root_cert_sn = @getAlipayRootCertSN()
    };

    var bizParams: map[string]any = {
      outer_order_no = outerOrderNo,
      biz_code = bizCode,
      identity_param = identityParam,
      merchant_config = merchantConfig
    };

    var textParams: map[string]string = {
    };

    protocol = @getConfig('protocol');
    method = 'POST';
    pathname = '/gateway.do';

    headers = {
      host = @getConfig('gatewayHost'),
      content-type = 'application/x-www-form-urlencoded;charset=utf-8'
    };

    query = {
      sign = @sign(systemParams, bizParams, textParams, @getConfig('merchantPrivateKey')),
      ... systemParams
    };

    body = @toUrlEncodedRequestBody(bizParams, textParams);
  } returns {
    var respMap: object = @readAsJson(__response, "alipay.user.certify.open.initialize");

    if (@isCertMode()) {
      if (@verify(respMap, @extractAlipayPublicKey(@getAlipayCertSN(respMap)))) {
        return @toRespModel(respMap);
      } 
    } else {
      if (@verify(respMap, @getConfig('alipayPublicKey'))) {
        return @toRespModel(respMap);
      } 
    }
    
    throw {
      message = '验签失败，请检查支付宝公钥设置是否正确。'
    }
    
  } runtime {
    connectTimeout = 15000,
    readTimeout = 15000,
    retry = {
      maxAttempts = 0
    }
  }

  function certify(certifyId: string): AlipayUserCertifyOpenCertifyResponse {
    var systemParams: map[string]string = {
      method = 'alipay.user.certify.open.certify',

      app_id = @getConfig('appId'),
      timestamp = @getTimestamp(),
      format = 'json',
      version = '1.0',
      alipay_sdk = @getSdkVersion(),
      charset = 'UTF-8',
      sign_type = @getConfig('signType'),
      app_cert_sn = @getMerchantCertSN(),
      alipay_root_cert_sn = @getAlipayRootCertSN()
    };

    var bizParams: map[string]any = {
      certify_id = certifyId
    };

    var textParams: map[string]string = {
    };

    var sign = @sign(systemParams, bizParams, textParams, @getConfig('merchantPrivateKey'));

    var response: map[string]string = {
      body = @generatePage('GET', systemParams, bizParams, textParams, sign)
    };
    return response;
  }

  api query(certifyId: string): AlipayUserCertifyOpenQueryResponse {
    var systemParams: map[string]string = {
      method = 'alipay.user.certify.open.query',

      app_id = @getConfig('appId'),
      timestamp = @getTimestamp(),
      format = 'json',
      version = '1.0',
      alipay_sdk = @getSdkVersion(),
      charset = 'UTF-8',
      sign_type = @getConfig('signType'),
      app_cert_sn = @getMerchantCertSN(),
      alipay_root_cert_sn = @getAlipayRootCertSN()
    };

    var bizParams: map[string]any = {
      certify_id = certifyId
    };

    var textParams: map[string]string = {
    };

    protocol = @getConfig('protocol');
    method = 'POST';
    pathname = '/gateway.do';

    headers = {
      host = @getConfig('gatewayHost'),
      content-type = 'application/x-www-form-urlencoded;charset=utf-8'
    };

    query = {
      sign = @sign(systemParams, bizParams, textParams, @getConfig('merchantPrivateKey')),
      ... systemParams
    };

    body = @toUrlEncodedRequestBody(bizParams, textParams);
  } returns {
    var respMap: object = @readAsJson(__response, "alipay.user.certify.open.query");

    if (@isCertMode()) {
      if (@verify(respMap, @extractAlipayPublicKey(@getAlipayCertSN(respMap)))) {
        return @toRespModel(respMap);
      } 
    } else {
      if (@verify(respMap, @getConfig('alipayPublicKey'))) {
        return @toRespModel(respMap);
      } 
    }
    
    throw {
      message = '验签失败，请检查支付宝公钥设置是否正确。'
    }
    
  } runtime {
    connectTimeout = 15000,
    readTimeout = 15000,
    retry = {
      maxAttempts = 0
    }
  }
}